#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   SessionControl_0x10_test.py
@Time    :   2022/07/06 13:31:28
@Author  :   **** 
@Version :   1.0
@Contact :   ****@chengtech.com
@License :   (C)Copyright 2022-2025
@Desc    :   None
'''
# here put the import lib
from pytest_assume.plugin import assume
import os
import sys
import logging
import time
import allure
import pytest
from collections.abc import Iterable
import binascii

from sqlalchemy.sql import True_

# 配置路径
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.abspath(os.path.dirname(curPath) + os.path.sep + ".")
sys.path.extend([
    rootPath,
    os.path.join(rootPath, 'commDriver'),
    os.path.join(rootPath, 'data'),
    os.path.join(rootPath, 'download')
])
logging.info(sys.path)

# 导入模块
from commDriver.modbus_plc import *
from DownLoad import *
import Set_up

sys.dont_write_bytecode = True

# 常量定义
NORMAL_VOLTAGE = 12
HIGH_VOLTAGE = 18.8
MIN_VOLTAGE = 0
VOLTAGE_DELAY = 0.5
RESTART_DELAY = 3
MAX_WAIT_ITERATIONS = 80
REPEAT_COUNT = 20
PROGRESS_10 = 10
PROGRESS_30 = 30
PROGRESS_50 = 50
PROGRESS_70 = 70
PROGRESS_90 = 90
CAN_ID_80 = 0x80
CAN_ID_66F = 0x66F
TEST_TIMEOUT = 30
FLASH_SUCCESS = True
FLASH_FAILURE = False

# PLC配置
PLC_PORT = 'COM4'
CANH_VBAT = 0x0000
CANH_GND = 0x0001
CANH_CANL = 0x0002
CANH_OPEN = 0x0003


class Test_Flash(object):
    '''固件刷写测试类，验证不同条件下的刷写行为'''
    @allure.severity('normal')
    @allure.story('Flash Test')
    @allure.title('正常工作电压刷写，应刷写成功')
    @allure.description('正常工作电压刷写，应刷写成功')
    @pytest.mark.repeat(5)
    def test_normal_voltage_flash(self, action, Driver):
        """正常工作电压刷写测试
        Args:
            action: 测试步骤标记
            Driver: 驱动实例集合
        """
        with allure.step('正常工作电压刷写'):
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            downloader.join()
            with assume: assert downloader.success_flag == FLASH_SUCCESS, "正常电压刷写失败"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == FLASH_SUCCESS, "刷写后设备状态异常"

    @allure.severity('normal')
    @allure.title('高电压刷写,应可刷写成功')
    @allure.description('高电压刷写,应能刷写成功')
    def test_high_voltage_flash(self, action, Driver):
        """高电压刷写测试
        Args:
            action: 测试步骤标记
            Driver: 驱动实例集合
        """
        with allure.step('高电压刷写'):
            Driver['power'].set_voltage(HIGH_VOLTAGE)

            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            downloader.join()
            with assume: assert downloader.success_flag, "高电压刷写失败"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal, "刷写后设备状态异常"

    # @allure.severity('normal')
    # @allure.title('连续多次刷写,每次刷写成功')
    # @allure.description('连续多次刷写，每次刷写成功')
    # @pytest.mark.repeat(REPEAT_COUNT)
    # def test_repeat_flash(self, action, Driver):
    #     """连续多次刷写测试
    #     Args:
    #         action: 测试步骤标记
    #         Driver: 驱动实例集合
    #     """
    #     with allure.step('连续多次刷写'):
    #         downloader = Download(
    #             Driver['CAN'],
    #             Driver['UDS'],
    #             Driver['UDSFun'],
    #             Set_up.flashDriverPath,
    #             Set_up.soft_path
    #         )
    #         downloader.join()
    #         with assume: assert downloader.success_flag, "重复刷写失败"
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal, "刷写后设备状态异常"

    @allure.severity('normal')
    @allure.title('数据传输到10%中断,再次重新烧录，可以烧录成功')
    @allure.description('数据传输到10%中断,再次重新烧录, 可以烧录成功!')
    def test_data_transfer_10_percent_interruption(self, action, Driver):
        """数据传输到10%中断后重试测试
        Args:
            action: 测试步骤标记
            Driver: 驱动实例集合
        """
        with allure.step('数据传输到10%中断后重试'):
            # 第一次下载 - 中断测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            
            iteration = 0
            progress_stuck = 0
            while True:
                iteration += 1
                if downloader.app and downloader.progress_number >= PROGRESS_10:
                    downloader.set_stop(True)
                    break
                
                time.sleep(1)
                
                if iteration == 1:
                    progress_stuck = downloader.progress_number
                elif iteration > MAX_WAIT_ITERATIONS and downloader.progress_number == progress_stuck:
                    downloader.set_stop(True)
                    break
            
            downloader.join()
            
            # 第二次下载 - 恢复测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            downloader.join()
            
            with assume: assert downloader.success_flag == FLASH_SUCCESS, "中断后重试刷写失败"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == FLASH_SUCCESS, "刷写后设备状态异常"

    @allure.severity('normal')
    @allure.title('数据传输到30%中断,再次重新烧录，可以烧录成功')
    @allure.description('数据传输到30%中断,再次重新烧录, 可以烧录成功!')
    def test_data_transfer_30_percent_interruption(self, action, Driver):                 
        with allure.step('flash ternination when tansimit 30%'):
            
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            i = 0
            while True:
                i +=1
                if (downloader.app == True) and (downloader.progress_number >= 30):
                    downloader.set_stop(True)
                    break
                else:
                    time.sleep(1)
                if i == 1:
                    progress_number = downloader.progress_number 
                if i > 80 and downloader.progress_number == progress_number:
                    downloader.set_stop(True)
                    break
            downloader.join()
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            downloader.join()
            with assume: assert downloader.success_flag == True
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == FLASH_SUCCESS, "刷写后设备状态异常"

    @allure.severity('normal')
    @allure.title('数据传输到50%中断,再次重新烧录,可以烧录成功')
    @allure.description('数据传输到50%中断,再次重新烧录,可以烧录成功!')
    def test_data_transfer_50_percent_interruption(self, action, Driver):
        """数据传输到50%中断后重试测试
        Args:
            action: 测试步骤标记
            Driver: 驱动实例集合
        """
        with allure.step('数据传输到50%中断后重试'):
            # 第一次下载 - 中断测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            
            iteration = 0
            progress_stuck = 0
            while True:
                iteration += 1
                if downloader.app and downloader.progress_number >= PROGRESS_50:
                    downloader.set_stop(True)
                    break
                time.sleep(1)
                
                if iteration == 1:
                    progress_stuck = downloader.progress_number
                elif iteration > MAX_WAIT_ITERATIONS and downloader.progress_number == progress_stuck:
                    downloader.set_stop(True)
                    break
            downloader.join()
            
            # 第二次下载 - 恢复测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            downloader.join()
            
            with assume: assert downloader.success_flag == FLASH_SUCCESS, "中断后重试刷写失败"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == FLASH_SUCCESS, "刷写后设备状态异常"

    @allure.severity('normal')
    @allure.title('数据传输到70%中断,再次重新烧录,可以烧录成功')
    @allure.description('数据传输到70%中断,再次重新烧录,可以烧录成功!')
    def test_data_transfer_70_percent_interruption(self, action, Driver):
        """数据传输到70%中断后重试测试
        Args:
            action: 测试步骤标记
            Driver: 驱动实例集合
        """
        with allure.step('数据传输到70%中断后重试'):
            # 第一次下载 - 中断测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            
            iteration = 0
            progress_stuck = 0
            while True:
                iteration += 1
                if downloader.app and downloader.progress_number >= PROGRESS_70:
                    downloader.set_stop(True)
                    break
                time.sleep(1)
                
                if iteration == 1:
                    progress_stuck = downloader.progress_number
                elif iteration > MAX_WAIT_ITERATIONS and downloader.progress_number == progress_stuck:
                    downloader.set_stop(True)
                    break
            
            # 第二次下载 - 恢复测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            downloader.join()
            
            with assume: assert downloader.success_flag == FLASH_SUCCESS, "中断后重试刷写失败"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('数据传输到90%中断,再次重新烧录,可以烧录成功')
    @allure.description('数据传输到90%中断,再次重新烧录,可以烧录成功!')
    def test_data_transfer_90_percent_interruption(self, action, Driver):
        """数据传输到90%中断后重试测试
        Args:
            action: 测试步骤标记
            Driver: 驱动实例集合
        """
        with allure.step('数据传输到90%中断后重试'):
            # 第一次下载 - 中断测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            
            iteration = 0
            progress_stuck = 0
            while True:
                iteration += 1
                if downloader.app and downloader.progress_number >= PROGRESS_90:
                    downloader.set_stop(True)
                    break
                time.sleep(1)
                
                if iteration == 1:
                    progress_stuck = downloader.progress_number
                elif iteration > MAX_WAIT_ITERATIONS and downloader.progress_number == progress_stuck:
                    downloader.set_stop(True)
                    break
            
            downloader.join()
            
            # 第二次下载 - 恢复测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            downloader.join()
            
            with assume: assert downloader.success_flag == FLASH_SUCCESS, "中断后重试刷写失败"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == FLASH_SUCCESS, "刷写后设备状态异常"

    @allure.severity('normal')
    @allure.title('数据传输30%后掉电,再次重新烧录,可以烧录成功')
    @allure.description('数据传输30%后掉电,再次重新烧录,可以烧录成功!')
    def test_data_transfer_30_percent_poweroff(self, action, Driver):
        """数据传输30%后掉电，再次重新烧录测试
        Args:
            action: 测试步骤标记
            Driver: 驱动实例集合
        """
        with allure.step('数据传输30%后掉电'):
            # 第一次下载 - 掉电测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            
            iteration = 0
            progress_stuck = 0
            while True:
                iteration += 1
                if downloader.app and downloader.progress_number >= PROGRESS_30:
                    Driver['CAN'].SetVolt(Driver, MIN_VOLTAGE, VOLTAGE_DELAY, 1)
                    break
                time.sleep(1)
                
                if iteration == 1:
                    progress_stuck = downloader.progress_number
                elif iteration > MAX_WAIT_ITERATIONS and downloader.progress_number == progress_stuck:
                    downloader.set_stop(True)
                    break
            
            downloader.join()
            Driver['CAN'].SetVolt(Driver, NORMAL_VOLTAGE, VOLTAGE_DELAY, 1)
            
            # 第二次下载 - 恢复测试
            downloader = Download(
                Driver['CAN'],
                Driver['UDS'],
                Driver['UDSFun'],
                Set_up.flashDriverPath,
                Set_up.soft_path
            )
            downloader.join()
            with assume: assert downloader.success_flag == FLASH_SUCCESS, "掉电后重试刷写失败"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == FLASH_SUCCESS, "刷写后设备状态异常"
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == FLASH_SUCCESS, "刷写后设备状态异常"

    # @allure.severity('normal')
    # @allure.title('数据传输中CANL短接Vbat_30%')
    # @allure.description('Flash abnormal termination by short CANH and Vbat when transmit 30%, flash failed!')
    # # @pytest.mark.skip()
    # def test_data_transfer_30_percent_short_canhtovbat(self,action,Driver):                   
    #     with allure.step('Short CANL and Vbat when tansimit 30%'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             i+=1
    #             if (downloader.app == True) and (downloader.progress_number >= 30):
    #                 Driver['CAN'].V_ConnectCanL_Vcc(True, 1)          #Short CANL and Vbat
    #                 break
    #             else:
    #                 time.sleep(1)

    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         Driver['CAN'].V_ConnectCanL_Vcc(False, 2)          #Open CANL and Vbat
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：数据传输中CANH短接GND_30%')
    # @allure.description('Flash abnormal termination by short CANH and GND when transmit 30%, flash failed!')
    # # @pytest.mark.skip()
    # def test_data_transfer_30_percent_short_canhtognd(self,action,Driver):                   
    #     with allure.step('Short CANH and GND when tansimit 30%'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             i+=1
    #             if (downloader.app == True) and (downloader.progress_number >= 30):
    #                 Driver['CAN'].V_ConnectCanH_GND(True, 1)          #Short CANH and GND
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['CAN'].V_ConnectCanH_GND(False, 2)          #Open CANH and GND
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('数据传输30%后短接CANH CANL,再次重新烧录,可以烧录成功')
    @allure.description('数据传输30%后短接CANH CANL,再次重新烧录,可以烧录成功!')
    # @pytest.mark.skip()
    def test_data_transfer_30_percent_short_canhtocanl(self,action,Driver):                   
        with allure.step('Short CANH and CANL when tansimit 30%'):
            
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            i = 0
            while True:
                i += 1
                if (downloader.app == True) and (downloader.progress_number >= 30):
                    Driver['CAN'].V_ConnectCanH_CanL(Driver, True, 1)          #Short CANH and CANL
                    break
                else:
                    time.sleep(1)
                if i == 1:
                    progress_number = downloader.progress_number 
                if i > 80 and downloader.progress_number == progress_number:
                    downloader.set_stop(True)
                    break
            downloader.join()
            Driver['CAN'].V_ConnectCanH_CanL(Driver,False, 2)  
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            downloader.join()
            with assume: assert downloader.success_flag == True
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：数据传输中CANH断开_30%')
    # @allure.description('Flash abnormal termination by open CANH when transmit 30%, flash failed!')
    # @pytest.mark.skip()
    # def test_data_transfer_30_percent_open_canh(self,action,Driver):               
    #     with allure.step('Open CANH when tansimit 30%'):
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             i+=1
    #             if (downloader.app == True) and (downloader.progress_number >= 30):
    #                 Driver['PLC'].write_single_coil(canh_open,0x0000)          #Open CANH
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 15 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['PLC'].write_single_coil(canh_open,0xFF00)          #Close CANH
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('内存擦除前掉电,再次重新烧录,可以烧录成功')
    @allure.description('内存擦除前掉电,再次重新烧录,可以烧录成功!')
    def test_poweroff_befor_erash_memory(self,action,Driver):                   
        with allure.step('Power off befor erash memory'):
            
            i = 0
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            while True:
                i += 1
                if (downloader.app == True) and (downloader.erashing == False):                     #擦除内存前的时间状态
                    Driver['CAN'].SetVolt(Driver, 0, 0.5, 1)
                    logging.info('set power status to off')
                    break
                else:
                    time.sleep(0.5)
                if i > 80:
                    downloader.set_stop(True)  
                    break
            downloader.join()
            Driver['CAN'].SetVolt(Driver, 12, 0.5, 1)
            self.restart_etc(Driver)
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            downloader.join()
            with assume: assert downloader.success_flag == True
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：内存擦除前CANL短接Vbat')
    # @allure.description('Short CANH and Vbat befor erash memory, flash failed!')
    # # @pytest.mark.skip()
    # def test_short_canhtovbat_befor_erash_memory(self,action,Driver):                   
    #     with allure.step('Short CANH and Vbat befor erash memory'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             if (downloader.app == True) and (downloader.erashing == False):                         #擦除内存前的时间状态
    #                 Driver['CAN'].V_ConnectCanL_Vcc(True, 1)         #Short CANL and Vbat
    #                 break
    #             else:
    #                 time.sleep(0.5)
    #             if i > 80:
    #                 downloader.set_stop(True)  
    #                 break
    #             i += 1
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['CAN'].V_ConnectCanL_Vcc(False, 1)          #Open CANL and Vbat
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    
    # @allure.severity('normal')
    # @allure.title('用例标题：内存擦除前CANH短接GND')
    # @allure.description('Short CANH and GND befor erash memory, flash failed!')
    # # @pytest.mark.skip()
    # def test_short_canhtognd_befor_erash_memory(self,action,Driver):                   
    #     with allure.step('Short CANH and GND befor erash memory'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             i += 1
    #             if (downloader.app == True) and (downloader.erashing == False):                         #擦除内存前的时间状态
    #                 Driver['CAN'].V_ConnectCanH_GND(True, 1)          #Short CANH and GND
    #                 break
    #             else:
    #                 time.sleep(0.5)
    #             if i > 80:
    #                 downloader.set_stop(True)  
    #                 break
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['CAN'].V_ConnectCanH_GND(False, 2)          #Open CANH and GND
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：内存擦除前CANH短接CANL')
    # @allure.description('Short CANH and CANL befor erash memory, flash failed!')
    # # @pytest.mark.skip()
    # def test_short_canhtocanl_befor_erash_memory(self,action,Driver):                   
    #     with allure.step('Short CANH and CANL befor erash memory'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             i += 1
    #             if (downloader.app == True) and (downloader.erashing == False):                         #擦除内存前的时间状态
    #                 Driver['CAN'].V_ConnectCanH_CanL(True, 1)           #Short CANH and CANL
    #                 break
    #             else:
    #                 time.sleep(0.5)
    #             if i > 80:
    #                 downloader.set_stop(True)  
    #                 break
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['CAN'].V_ConnectCanH_CanL(False, 2)          #Open CANH and GND
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：内存擦除前CANH断开')
    # @allure.description('Open CANH befor erash memory, flash failed!')
    # @pytest.mark.skip()
    # def test_open_canh_befor_erash_memory(self,action,Driver):                   
    #     with allure.step('Open CANH befor erash memory'):
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         while True:
    #             if (downloader.app == True) and (downloader.erashing == False):                         #擦除内存前的时间状态
    #                 Driver['PLC'].write_single_coil(canh_open,0x0000)          #Open CANH
    #                 break
    #             else:
    #                 time.sleep(0.5)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['power'].SetVolt(Driver,  0, 0.5)
    #         Driver['PLC'].write_single_coil(canh_open,0xFF00)          #Close CANH
    #         time.sleep(1)
    #         Driver['power'].set_voltage(14)
    #         time.sleep(3)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('内存擦除中掉电,再次重新烧录,可以烧录成功')
    @allure.description('内存擦除中掉电,再次重新烧录,可以烧录成功!')
    def test_poweroff_erash_memory(self,action,Driver):                      
        with allure.step('Power off on erash memory'):
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            i = 0
            while True:
                i += 1
                if (downloader.app == True) and (downloader.erashing == True):                     #擦除内存中的时间状态
                    Driver['CAN'].SetVolt(Driver, 0, 0.5, 1)
                    logging.info('set power status to off')
                    break
                else:
                    time.sleep(0.5)
                if i > 80:
                    downloader.set_stop(True)  
                    break
            downloader.join()
            Driver['CAN'].SetVolt(Driver, 12, 0.5, 1)
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            downloader.join()
            with assume: assert downloader.success_flag == True
            self.restart_etc(Driver)
            time.sleep(3)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：内存擦除中CANL短接Vbat')
    # @allure.description('Short CANH and Vbat on erash memory, flash failed!')
    # # @pytest.mark.skip()
    # def test_short_canhtovbat_erash_memory(self,action,Driver):                   
    #     with allure.step('Short CANH and Vbat on erash memory'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             i += 1
    #             if (downloader.app == True) and (downloader.erashing == True):                         #擦除内存中的时间状态
    #                 Driver['CAN'].V_ConnectCanL_Vcc(True, 1)           #Short CANL and Vbat
    #                 break
    #             else:
    #                 time.sleep(0.5)
    #             if i > 80:
    #                 downloader.set_stop(True)  
    #                 break
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['CAN'].V_ConnectCanL_Vcc(False, 2)                   #Open CANL and Vbat
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：内存擦除中CANH短接GND')
    # @allure.description('Short CANH and GND on erash memory, flash failed!')
    # # @pytest.mark.skip()
    # def test_short_canhtognd_erash_memory(self,action,Driver):                   
    #     with allure.step('Short CANH and GND on erash memory'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         i = 0
    #         while True:
    #             i += 1
    #             if (downloader.app == True) and (downloader.erashing == True):                         #擦除内存中的时间状态
    #                 Driver['CAN'].V_ConnectCanH_GND(True, 1)           #Short CANH and GND
    #                 break
    #             else:
    #                 time.sleep(0.5)
    #             if i > 80:
    #                 downloader.set_stop(True)  
    #                 break
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['CAN'].V_ConnectCanH_GND(False, 2)           #Open CANH and GND
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('内存擦除中CANH短接CANL，再次重新烧录，可烧录成功')
    @allure.description('内存擦除中CANH短接CANL，再次重新烧录，可烧录成功!')
    def test_short_canhtocanl_erash_memory(self,action,Driver):                   
        with allure.step('Short CANH and CANL on erash memory'):
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            i = 0
            while True:
                i += 1
                if (downloader.app == True) and (downloader.erashing == True):                         #擦除内存中的时间状态
                    Driver['CAN'].V_ConnectCanH_CanL(Driver, True, 1)           #Short CANH and CANL
                    break
                else:
                    time.sleep(0.5)
                if i > 80:
                    downloader.set_stop(True)  
                    break

            downloader.join()
            Driver['CAN'].V_ConnectCanH_CanL(Driver, False, 2)                   #Open CANH and CANL
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            downloader.join()
            with assume: assert downloader.success_flag == True
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：内存擦除中CANH断开')
    # @allure.description('Open CANH on erash memory, flash failed!')
    # @pytest.mark.skip()
    # def test_open_canh_erash_memory(self,action,Driver):                   
    #     with allure.step('Open CANH on erash memory'):
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         while True:
    #             if (downloader.app == True) and (downloader.erashing == True):                         #擦除内存中的时间状态
    #                 Driver['PLC'].write_single_coil(canh_open,0x0000)          #Open CANH
    #                 break
    #             else:
    #                 time.sleep(0.5)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         Driver['power'].SetVolt(Driver,  0, 0.5)
    #         Driver['PLC'].write_single_coil(canh_open,0xFF00)          #Close CANH
    #         time.sleep(1)
    #         Driver['power'].set_voltage(14)
    #         time.sleep(3)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：故障测试后在正常刷写一次')                             #描述歧义
    # @allure.description('Flash after fault test , flash failed!')
    # def test_flash_after_fault(self,action,Driver):  
    #     Driver['power'].set_voltage(18.8)
    #     Driver['UDSFun'].req_and_res_can([0x19,0x02,0x09],3)
    #     Driver['power'].set_voltage(12)
    #     with allure.step('Flash after fault test'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('内存擦除后退出,再次重新烧录,可以烧录成功')                             
    @allure.description('内存擦除后退出,再次重新烧录,可以烧录成功!')
    def test_Exit_after_erash_memory(self,action,Driver):                   
        with allure.step('Flash by invalid app test'):
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            i = 0
            while True:
                i += 1
                if (downloader.app == True) and (downloader.erashing == True):                         #擦除内存中的时间状态
                    downloader.set_stop(True)                                                   #停止刷新
                    break
                else:
                    time.sleep(0.5)
                if i > 80:
                    downloader.set_stop(True)  
                    break
            downloader.join()
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            downloader.join()
            with assume: assert downloader.success_flag == True
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('正常进入bootloader模式后退出bootloader模式')                             
    # @allure.description('Flash by exit bootloader mode , flash failed!')
    # def test_exit_bootloader_mode(self,action,Driver):                   
    #     with allure.step('Flash by exit bootloader test'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,exit=True)
    #         downloader.join()
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    
    # @allure.severity('normal')
    # @allure.title('CRC校验错误测试')                             
    # @allure.description('Flash by CRC Check Error , flash failed!')
    # def test_crc_error(self,action,Driver):                       
    #     with allure.step('Flash by CRC Error'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,crcerror=True)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('功能寻址TP报文对下载影响,应可正常烧录成功')                             
    @allure.description('功能寻址TP报文对下载影响,应可正常烧录成功!')
    def test_function_tp(self,action,Driver):                       
        with allure.step('Flash by Function TP'):
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
            i = 0
            while downloader.finish == False:
                i += 1
                if downloader.app == True:
                    uds_rep,_ = Driver['UDSFun'].req_and_res_can([0x3E,0x80],2)
                time.sleep(0.5)
                if i > 800:
                    downloader.set_stop(True)  
                    break
            downloader.join()
            with assume: assert downloader.success_flag == True
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('跳过编程预条件检查，刷写失败，断电重启后设备运行正常')                             
    @allure.description('Flash by skip precheck , flash failed!')
    def test_skip_precheck(self,action,Driver):                       
        with allure.step('Flash by ship precheck'):
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,skipprecheck=True)
            downloader.join()
            with assume: assert downloader.success_flag == False
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    @allure.severity('normal')
    @allure.title('跳过Flash Driver进行刷写，刷写失败，断电重启后设备运行正常')                             
    @allure.description('Flash by skip Flash Driver , flash failed!')
    def test_skip_flashdriver(self,action,Driver):                   
        with allure.step('Flash by ship Flash Driver'):
            
            downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,skipflash=True)
            downloader.join()
            with assume: assert downloader.success_flag == False
            self.restart_etc(Driver)
            downloader.post_abnormal_termination_startup()
            with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.story('Flash Test')
    # @allure.title('用例标题：升级错误的软件')
    # @allure.description('Update program by normal voltage, flash success!')
    # def test_failed_soft_flash(self,action,Driver):                   
    #     """ 
    #         @param              :    description
    #         @action             :    mark the start and end of the test step, import from conftest
    #         @Driver             :    called but not excuted, import from conftest
    #     """
    #     with allure.step('Flash on normal voltage'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],error_path)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.title('用例标题：只升级boot')                             
    # @allure.description('only Flash boot, flash failed!')
    # def test_only_update_boot(self,action,Driver):                   
    #     with allure.step('Flash by ship Flash Driver'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,skipapp=True)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True


    # @allure.severity('normal')
    # @allure.title('用例标题：只升级boot')                             
    # @allure.description('only Flash app, flash failed!')
    # def test_only_update_app(self,action,Driver):                   
    #     with allure.step('Flash by ship Flash Driver'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,skipboot=True)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True


    # @allure.severity('normal')
    # @allure.story('Flash Test')
    # @allure.title('用例标题：升级错误的软件')
    # @allure.description('Update program by normal voltage, flash success!')
    # def test_errorApp_TrueBoot_flash(self,action,Driver):                   
    #     """ 
    #         @param              :    description
    #         @action             :    mark the start and end of the test step, import from conftest
    #         @Driver             :    called but not excuted, import from conftest
    #     """
    #     with allure.step('Flash on normal voltage'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,errorApp=True)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    # @allure.severity('normal')
    # @allure.story('Flash Test')
    # @allure.title('用例标题：升级错误的软件')
    # @allure.description('Update program by normal voltage, flash success!')
    # def test_TrueApp_errorBoot_flash(self,action,Driver):                   
    #     """ 
    #         @param              :    description
    #         @action             :    mark the start and end of the test step, import from conftest
    #         @Driver             :    called but not excuted, import from conftest
    #     """
    #     with allure.step('Flash on normal voltage'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path,errorBoot=True)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == False
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    
    # @allure.severity('normal')
    # @allure.story('Flash Test')
    # @allure.title('用例标题：降级升级后检查CAN通信再次升级新软件')
    # @allure.description('Update program by normal voltage after downgrade program, flash success!')
    # def test_downgrade_flash(self,action,Driver):                   
    #     """ 
    #         @param              :    description
    #         @action             :    mark the start and end of the test step, import from conftest
    #         @Driver             :    called but not excuted, import from conftest
    #     """
    #     iStep = 1
    #     with allure.step('Downgrade on normal voltage'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.oldSet_up.flashDriverPath, Set_up.soft_path,skiprestart = True)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         # self.restart_etc(Driver)
    #         # downloader.post_abnormal_termination_startup()
    #         # with assume: assert downloader.normal == False

    #     time.sleep(1)
    #     Driver['CAN'].checkReqResp(Driver, "2E F1 A1 FF FF FF FF FF FF FF FF", '6E F1 A1', 3, iStep, True)
    #     iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '2E 21 00 ' + Set_up.VariantCoding[0], '6E 21 00', 0, iStep, False)

    #     iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '22 21 00', '62 21 00 ' + Set_up.VariantCoding[0], 0, iStep, False) 

    #     self.restart_etc(Driver)

    #     with allure.step('Flash on normal voltage'):
            
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    

    # ###烧录新增用例###
    # @allure.severity('normal')
    # @allure.title('用例标题：APP数据传输到10%中断后发送1101')
    # @allure.description('send 1101 after APP transfer termination')
    # def test_App_transfer_termination_1101(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipboot=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '11 01', '51 01', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)

    # @allure.severity('normal')
    # @allure.title('用例标题：APP数据传输到10%中断后发送1001')
    # @allure.description('send 1001 after APP transfer termination')
    # @pytest.mark.repeat(10)
    # def test_App_transfer_termination_1001(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipboot=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 01', '50 01', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)

    
    # @allure.severity('normal')
    # @allure.title('用例标题：APP数据传输到10%中断后发送1002')
    # @allure.description('send 1002 after APP transfer termination')
    # def test_App_transfer_termination_1002(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipboot=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 02', '50 02', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)

    
    # @allure.severity('normal')
    # @allure.title('用例标题：APP数据传输到10%中断后发送1003')
    # @allure.description('send 1003 after APP transfer termination')
    # def test_App_transfer_termination_1003(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipboot=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 03', '7F 10 7E', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)


    
    # @allure.severity('normal')
    # @allure.title('用例标题：Boot数据传输到10%中断后发送1101')
    # @allure.description('send 1101 after Boot transfer termination')
    # def test_Boot_transfer_termination_1101(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipapp=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '11 01', '51 01', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)

    # @allure.severity('normal')
    # @allure.title('用例标题：Boot数据传输到10%中断后发送1001')
    # @allure.description('send 1001 after Boot transfer termination')
    # def test_Boot_transfer_termination_1001(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipapp=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 01', '50 01', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)

    
    # @allure.severity('normal')
    # @allure.title('用例标题：Boot数据传输到10%中断后发送1002')
    # @allure.description('send 1002 after Boot transfer termination')
    # def test_Boot_transfer_termination_1002(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipapp=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 02', '50 02', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)

    
    # @allure.severity('normal')
    # @allure.title('用例标题：Boot数据传输到10%中断后发送1003')
    # @allure.description('send 1003 after Boot transfer termination')
    # def test_Boot_transfer_termination_1003(self,action,Driver):                   
    #     with allure.step('flash ternination when tansimit 10%'):
    #         iStep = 0
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],Set_up.flashDriverPath, Set_up.soft_path, skipapp=True,isContinue=False)
    #         i = 0
    #         while True:
    #             i +=1
    #             if (downloader.app == True) and (downloader.progress_number >= 10):
    #                 downloader.set_stop(True)
    #                 break
    #             else:
    #                 time.sleep(1)
    #             if i == 1:
    #                 progress_number = downloader.progress_number 
    #             if i > 80 and downloader.progress_number == progress_number:
    #                 downloader.set_stop(True)
    #                 break
    #         downloader.join()

    #         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '10 03', '7F 10 7E', 0, iStep)
    #         with assume: assert size > 0

    #         logging.info('Wait 30 seconds')
    #         time.sleep(30)
    #         downloader.post_abnormal_termination_startup()

    #         self.checkPcanSignal(Driver)

    #         self.test_normal_voltage_flash(action,Driver)


    # @allure.severity('normal')
    # @allure.title('用例标题：只升级boot')                             
    # @allure.description('only Flash app, flash failed!')
    # @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/62fc94a1cfaa81dc60bed3f3/cases')
    # def test_app_NotMach_boot(self,action,Driver):                   
    #     with allure.step('Flash by ship Flash Driver'):
    #         erash_startaddress = [0x00,0x05,0x00,0x00]
    #         erash_size = [0x00,0x08,0x4A,0x96]
    #         downloader = Download(Driver['CAN'],Driver['UDS'],Driver['UDSFun'],errorApp_path,skipboot=True)
    #         downloader.join()
    #         with assume: assert downloader.success_flag == True
    #         self.restart_etc(Driver)
    #         downloader.post_abnormal_termination_startup()
    #         with assume: assert downloader.normal == True

    def restart_etc(self, Driver):
        """重启ETC设备
        Args:
            Driver: 驱动实例集合
        """
        Driver['power'].set_voltage(MIN_VOLTAGE)
        time.sleep(VOLTAGE_DELAY)
        Driver['power'].set_voltage(NORMAL_VOLTAGE)
        time.sleep(RESTART_DELAY)

    def check_pcan_signal(self, Driver):
        """检查CAN信号是否正常
        Args:
            Driver: 驱动实例集合
        """
        Driver['CAN2'].ClearBuffer()  # 清缓存
        time.sleep(1)
        all_data, buffer_size = Driver['CAN2'].read_frame()
        
        # 检查CAN ID 0x80
        response_data_80 = all_data[all_data['AIdentifier'] == CAN_ID_80]
        count_80 = len(response_data_80)
        
        # 检查CAN ID 0x66F
        response_data_66F = all_data[all_data['AIdentifier'] == CAN_ID_66F]
        count_66F = len(response_data_66F)
        
        # 记录接收到的数据
        self._log_can_data(CAN_ID_80, response_data_80, count_80)
        self._log_can_data(CAN_ID_66F, response_data_66F, count_66F)
        
        # 验证至少有一个CAN ID有响应
        with assume: 
            assert (count_66F > 0 or count_80 > 0), f"CAN信号检查失败 - ID 0x80: {count_80} 帧, ID 0x66F: {count_66F} 帧"

    def _log_can_data(self, can_id, data_frame, count):
        """记录CAN数据到日志
        Args:
            can_id: CAN标识符
            data_frame: 数据帧
            count: 帧数
        """
        receive_data = []
        try:
            if count > 0:
                last_data = data_frame.iloc[0]['ADatas']
                receive_data = [last_data[i] for i in range(8)]
        except Exception as e:
            logging.warning(f"解析CAN数据失败: {str(e)}")
            
        data_str = binascii.b2a_hex(bytearray(receive_data), b' ').decode()
        logging.info(f'receive_ID = [{can_id:X}], receive_Data = [{data_str}], count = [{count}]')